/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package model

/*
* CreatedId 创建ID
* PlatformType 平台类型,1为云上包周期订单,2为平台包周期订单
* UserId 用户ID
* CloudUserId 云上用户ID
* OrderId 账单对应订单号
* CloudOrderId 云上订单号,关联的云上订单ID,仅云上包周期资源有效
* CloudResourceId 关联的云上资源ID
* Billcycle 账期,账期所在月份,格式YYYY-MM，UTC时间
* ServiceTypeCode 云服务类型编码
* ServiceTypeName 云服务类型名称
* ResourceTypeCode 资源类型编码
* ResourceTypeName 资源类型名称
* RegionCode 区域编码
* RegionName 区域名称
* ChargeMode 计费模式 1.包年/包月 3.按需 10.预留实例
* EffectiveTime 资源生效时间。
* ExpireTime 资源消费结束时间。
计费模式为包年/包月和预留实例场景时为订单的支付时间。
计费模式为按需场景时为话单的生/失效时间。
* TradeId 订单ID或交易ID，扣费维度的唯一标识，云上账单自带，系统账单UUID生成
对于云上包周期订单,tradeId为云上包周期订单号,对于云上按需订单，
* TradeTime 交易时间，某条消费记录对应的扣费时间。
* BillType 账单类型
1：消费-新购
2：消费-续订
3：消费-变更
4：退款-退订
5：消费-使用
8：消费-自动续订
9：调账-补偿
14：消费-服务支持计划月末扣费
16：调账-扣费
18：消费-按月付费
20：退款-变更
* BillStatus 支付状态。
1：已支付
2：未结清
3：未结算
* OfficialAmount   	官网价。单位：元      official_amount = official_discount_amount + erase_amount + consume_amount
* OfficialDiscountAmount 折扣金额。单位：元。
* EraseAmount    	抹零金额。单位：元。
* ConsumeAmount  应付金额，包括现金券和储值卡和代金券金额。单位：元。
consume_amount的值等于cash_amount，credit_amount，coupon_amount，flexipurchase_coupon_amount，stored_value_card_amount，bonus_amount，debt_amount，writeoff_amount的总和。
* CashAmount  现金支付金额。单位：元
* CreditAmount  信用额度支付金额。单位：元。
* CouponAmount  代金券支付金额。单位：元。
* FlexipurchaseCouponAmount 现金券支付金额。单位：元。
* StoredValueCardAmount 储值卡支付金额。单位：元。
* DebtAmount     欠费金额。单位：元。       对于月结客户，欠费金额即页面上的月度结算金额。
* WriteOffAmount   欠费核销金额。单位：元。
*/
const (
	//字段数目
	FieldNameNum                       = 34
	BillIdFieldName                    = "bill_id"
	CreatedIdFieldName                 = "created_id"
	PlatformTypeFieldName              = "platform_type"
	UserIdFieldName                    = "user_id"
	CloudUserIdFieldName               = "cloud_user_id"
	OrderIdFieldName                   = "order_id"
	BillCycleFieldName                 = "bill_cycle"
	TradeIdFieldName                   = "trade_id"
	TradeTimeFieldName                 = "trade_time"
	EffectiveTimeFieldName             = "effective_time"
	ExpireTimeFieldName                = "expire_time"
	CurrencyFieldName                  = "currency"
	ChargeModeFieldName                = "charge_mode"
	BillTypeFieldName                  = "bill_type"
	BillStatusFieldName                = "bill_status"
	CloudOrderIdFieldName              = "cloud_order_id"
	CloudResourceIdFieldName           = "cloud_resource_id"
	ServiceTypeCodeFieldName           = "service_type_code"
	ServiceTypeNameFieldName           = "service_type_name"
	ResourceTypeCodeFieldName          = "resource_type_code"
	ResourceTypeNameFieldName          = "resource_type_name"
	RegionCodeFieldName                = "region_code"
	RegionNameFieldName                = "region_name"
	ConsumeAmountFieldName             = "consume_amount"
	OfficialAmountFieldName            = "official_amount"
	OfficialDiscountAmountFieldName    = "official_discount_amount"
	EraseAmountFieldName               = "erase_amount"
	CashAmountFieldName                = "cash_amount"
	CreditAmountFieldName              = "credit_amount"
	CouponAmountFieldName              = "coupon_amount"
	FlexipurchaseCouponAmountFieldName = "flexi_purchase_coupon_amount"
	StoredValueCardAmountFieldName     = "stored_value_card_amount"
	DebtAmountFieldName                = "debt_amount"
	WriteOffAmountFieldName            = "write_off_amount"
)

type Bill struct {
	BillBasic
	BillTradeDetail
	BillCloudDetail
	BillServiceDetail
	BillAmount
}
type BillBasic struct {
	CreatedId    int64  `orm:"column(created_id);auto;type(int64)"`
	BillCycle    string `orm:"column(bill_cycle);size(16)"`
	PlatformType string `orm:"column(platform_type);size(16)"`
	BillId       string `orm:"column(bill_id);size(64);index"`
	UserId       string `orm:"column(user_id);size(64);"`
	CloudUserId  string `orm:"column(cloud_user_id);size(64);"`
	OrderId      string `orm:"column(order_id);size(64);index"`
	TradeId      string `orm:"column(trade_id);size(64);"`
	TradeTime    string `orm:"column(trade_time);size(32)"`
}
type BillTradeDetail struct {
	EffectiveTime string `orm:"column(effective_time);size(32)"`
	ExpireTime    string `orm:"column(expire_time);size(32)"`
	Currency      string `orm:"column(currency);size(16)"`
	ChargeMode    string `orm:"column(charge_mode);size(8)"`
	BillType      int32  `orm:"column(bill_type);type(int32)"`
	BillStatus    int32  `orm:"column(bill_status);type(int32)"`
}
type BillCloudDetail struct {
	CloudOrderId    string `orm:"column(cloud_order_id);size(64)"`
	CloudResourceId string `orm:"column(cloud_resource_id);size(64)"`
}
type BillServiceDetail struct {
	ServiceTypeCode  string `orm:"column(service_type_code);size(32)"`
	ServiceTypeName  string `orm:"column(service_type_name);size(32)"`
	ResourceTypeCode string `orm:"column(resource_type_code);size(32)"`
	ResourceTypeName string `orm:"column(resource_type_name);size(32)"`
	RegionCode       string `orm:"column(region_code);size(32)"`
	RegionName       string `orm:"column(region_name);size(16)"`
}
type BillAmount struct {
	ConsumeAmount             float64 `orm:"column(consume_amount);digits(17);decimals(2)"`
	OfficialAmount            float64 `orm:"column(official_amount);digits(17);decimals(4)"`
	OfficialDiscountAmount    float64 `orm:"column(official_discount_amount);digits(17);decimals(4)"`
	EraseAmount               float64 `orm:"column(erase_amount);digits(17);decimals(4)"`
	CashAmount                float64 `orm:"column(cash_amount);digits(17);decimals(4)"`
	CreditAmount              float64 `orm:"column(credit_amount);digits(17);decimals(4)"`
	CouponAmount              float64 `orm:"column(coupon_amount);digits(17);decimals(4)"`
	FlexipurchaseCouponAmount float64 `orm:"column(flexi_purchase_coupon_amount);digits(17);decimals(4)"`
	StoredValueCardAmount     float64 `orm:"column(stored_value_card_amount);digits(17);decimals(4)"`
	DebtAmount                float64 `orm:"column(debt_amount);digits(17);decimals(4)"`
	WriteOffAmount            float64 `orm:"column(write_off_amount);digits(17);decimals(4)"`
}

// 增加账单的其他属性
func (bill *Bill) AddBillCloudDetail(cloudOrderId, cloudResourceId *string) {
	billCloudDetail := createBillCloudDetail(cloudOrderId, cloudResourceId)
	bill.BillCloudDetail = *billCloudDetail
}
func (bill *Bill) AddBillServiceDetail(serviceTypeCode, serviceTypeName, resourceTypeCode, resourceTypeName, regionCode, regionName *string) {
	billServiceDetail := createBillServiceDetail(serviceTypeCode, serviceTypeName, resourceTypeCode, resourceTypeName, regionCode, regionName)
	bill.BillServiceDetail = *billServiceDetail
}
func (bill *Bill) AddBillAmount(consumeAmount, officialAmount, officialDiscountAmount, eraseAmount, cashAmount, creditAmount, couponAmount, flexipurchaseCouponAmount, storedValueCardAmount, debtAmount, writeOffAmount *float64) {
	billAmount := createBillAmount(consumeAmount, officialAmount, officialDiscountAmount, eraseAmount, cashAmount, creditAmount, couponAmount, flexipurchaseCouponAmount, storedValueCardAmount, debtAmount, writeOffAmount)
	bill.BillAmount = *billAmount
}
func (bill *Bill) AddBillTradeDetail(effectiveTime, expireTime, currency, chargeMode *string, billType int32, billStatus *int32) {
	billTradeDetail := createBillTradeDetail(effectiveTime, expireTime, currency, chargeMode, billType, billStatus)
	bill.BillTradeDetail = *billTradeDetail
}

func createBillTradeDetail(effectiveTime, expireTime, currency, chargeMode *string, billType int32, billStatus *int32) *BillTradeDetail {
	billTradeDetail := &BillTradeDetail{
		BillType: billType,
	}
	if effectiveTime != nil {
		billTradeDetail.EffectiveTime = *effectiveTime
	}
	if expireTime != nil {
		billTradeDetail.ExpireTime = *expireTime
	}
	if currency != nil {
		billTradeDetail.Currency = *currency
	}
	if chargeMode != nil {
		billTradeDetail.ChargeMode = *chargeMode
	}
	if billStatus != nil {
		billTradeDetail.BillStatus = *billStatus
	}
	return billTradeDetail
}

// 创建账单对象属性
func createBillCloudDetail(cloudOrderId, cloudResourceId *string) *BillCloudDetail {
	billCloudDetail := &BillCloudDetail{}
	if cloudOrderId != nil {
		billCloudDetail.CloudOrderId = *cloudOrderId
	}
	if cloudResourceId != nil {
		billCloudDetail.CloudResourceId = *cloudResourceId
	}
	return billCloudDetail
}
func createBillServiceDetail(serviceTypeCode, serviceTypeName, resourceTypeCode, resourceTypeName, regionCode, regionName *string) *BillServiceDetail {
	billServiceDetail := BillServiceDetail{}
	if serviceTypeCode != nil {
		billServiceDetail.ServiceTypeCode = *serviceTypeCode
	}
	if serviceTypeName != nil {
		billServiceDetail.ServiceTypeName = *serviceTypeName
	}
	if resourceTypeCode != nil {
		billServiceDetail.ResourceTypeCode = *resourceTypeCode
	}
	if resourceTypeName != nil {
		billServiceDetail.ResourceTypeName = *resourceTypeName
	}
	if regionCode != nil {
		billServiceDetail.RegionCode = *regionCode
	}
	if regionName != nil {
		billServiceDetail.RegionName = *regionName
	}
	return &billServiceDetail
}
func createBillAmount(consumeAmount, officialAmount, officialDiscountAmount, eraseAmount, cashAmount, creditAmount, couponAmount, flexipurchaseCouponAmount, storedValueCardAmount, debtAmount, writeOffAmount *float64) *BillAmount {
	billAmount := &BillAmount{}
	if consumeAmount != nil {
		billAmount.ConsumeAmount = *consumeAmount
	}
	if officialAmount != nil {
		billAmount.OfficialAmount = *officialAmount
	}
	if officialDiscountAmount != nil {
		billAmount.OfficialDiscountAmount = *officialDiscountAmount
	}
	if eraseAmount != nil {
		billAmount.EraseAmount = *eraseAmount
	}
	if cashAmount != nil {
		billAmount.CashAmount = *cashAmount
	}
	if creditAmount != nil {
		billAmount.CreditAmount = *creditAmount
	}
	if couponAmount != nil {
		billAmount.CouponAmount = *couponAmount
	}
	if flexipurchaseCouponAmount != nil {
		billAmount.FlexipurchaseCouponAmount = *flexipurchaseCouponAmount
	}
	if storedValueCardAmount != nil {
		billAmount.StoredValueCardAmount = *storedValueCardAmount
	}
	if debtAmount != nil {
		billAmount.DebtAmount = *debtAmount
	}
	if writeOffAmount != nil {
		billAmount.WriteOffAmount = *writeOffAmount
	}
	return billAmount
}
